<?php

declare(strict_types=1);

namespace App\Service\Business;

use App\Constants\Menu\MenuBelongToEnum;
use App\Constants\Menu\MenuStatusEnum;
use App\Constants\Role\RoleStatusEnum;
use App\Constants\User\UserStatusEnum;
use App\Service\Access\MenuAccess;
use App\Service\Access\UserAccess;
use App\Service\Access\UserRoleAccess;
use Hyperf\Di\Annotation\Inject;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

/**
 * 用户-业务类
 */
class UserBusiness extends BaseBusiness
{
        #[Inject]
        protected UserAccess $UserAccess;

        /**
         * 用户名登录
         * @return array
         */
        public function loginUsername(): array
        {
                $arrUser = $this->UserAccess->first([
                        'wheres' => ['username' => $this->request->input('username')],
                        'fields' => ['userId', 'password', 'salt', 'status', 'loginFinallyTime', 'loginFinallyIp']
                ]);
                if (!$arrUser) return businessError(trans('user.tip.usernameOrPasswordError'));
                $strPassword = md5(md5($this->request->input('password')) . $arrUser['salt']);
                if ($arrUser['password'] !== $strPassword) {
                        return businessError(trans('user.tip.usernameOrPasswordError'));
                }
                if ($arrUser['status'] !== UserStatusEnum::DEFINITION_1->value) {
                        return businessError(trans('user.tip.disabled'));
                }
                $this->UserAccess->updateById([
                        'userId' => $arrUser['userId'],
                        'loginLastTime' => $arrUser['loginFinallyTime'],
                        'loginLastIp' => $arrUser['loginFinallyIp'],
                        'loginFinallyTime' => $this->request->getAttribute('timestamp'),
                        'loginFinallyIp' => $this->request->getHeaderLine('x-real-ip') ?? '',
                ]);
                $arrEncryptData = [
                        'userId' => $arrUser['userId'],
                        'password' => $arrUser['password'],
                        'loginFinallyTime' => $this->request->getAttribute('timestamp'),
                ];
                if ($this->request->hasHeader('user-agent')) {
                        $arrEncryptData['userAgent'] = $this->request->getHeaderLine('user-agent');
                }
                if ($this->request->hasHeader('referer')) {
                        $arrEncryptData['referer'] = $this->request->getHeaderLine('referer');
                }
                $joinEncryptData = json_encode($arrEncryptData, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
                $strEncrypt = customizeEncryptDecrypt($joinEncryptData, 1);
                $arrResult = ['token' => $strEncrypt];
                return businessSuccess($arrResult);
        }

        /**
         * 获取当前登录者信息
         * @return array
         */
        function info(): array
        {
                $arrResult = $this->UserAccess->find($this->request->getAttribute('userId'),
                        ['name', 'mobile', 'username']);
                return businessSuccess($arrResult);
        }

        /**
         * 分页
         * @param array $inject
         * @return array
         */
        public function paginate(array $inject = []): array
        {
                $arrQueryResult = $this->UserAccess->paginate($inject);
                $arrResult = [
                        'page' => $arrQueryResult['current_page'],
                        'limit' => $arrQueryResult['per_page'],
                        'total' => $arrQueryResult['total'],
                        'list' => $arrQueryResult['data'],
                ];
                return businessSuccess($arrResult);
        }

        /**
         * 创建
         * @return array
         * @throws ContainerExceptionInterface
         * @throws NotFoundExceptionInterface
         */
        public function create(): array
        {
                $strSalt = strval(mt_rand(1000, 9999));
                $arrInsert = [
                        'userSnowflakeId' => snowflakeId(),
                        'name' => $this->request->input('name'),
                        'mobile' => $this->request->input('mobile'),
                        'username' => $this->request->input('username'),
                        'password' => md5(md5($this->request->input('password')) . $strSalt),
                        'salt' => $strSalt,
                        'status' => $this->request->input('status'),
                        'createTime' => $this->request->getAttribute('timestamp'),
                ];
                $intUserId = $this->UserAccess->insertGetId($arrInsert);
                if (!$intUserId) return businessError();
                $this->createOperateLog([], $arrInsert);
                return businessSuccess(['userId' => $intUserId]);
        }

        /**
         * 更新
         * @return array
         * @throws ContainerExceptionInterface
         * @throws NotFoundExceptionInterface
         */
        public function update(): array
        {
                $arrData = $this->UserAccess->find($this->request->input('userId'), ['name', 'username', 'status']);
                $arrUpdate = [
                        'userId' => $this->request->input('userId'),
                        'name' => $this->request->input('name'),
                        'username' => $this->request->input('username'),
                        'status' => $this->request->input('status'),
                        'updateTime' => $this->request->getAttribute('timestamp'),
                ];
                $intEffectRow = $this->UserAccess->updateById($arrUpdate);
                if (!$intEffectRow) return businessError();
                $this->createOperateLog($arrData, $arrUpdate);
                return businessSuccess();
        }

        /**
         * 更新密码
         * @return array
         * @throws ContainerExceptionInterface
         * @throws NotFoundExceptionInterface
         */
        public function updatePassword(): array
        {
                $strSalt = strval(mt_rand(1000, 9999));
                $arrData = $this->UserAccess->find($this->request->input('userId'), ['password']);
                $arrUpdate = [
                        'userId' => $this->request->input('userId'),
                        'password' => md5(md5($this->request->input('password')) . $strSalt),
                        'salt' => $strSalt,
                        'updateTime' => $this->request->getAttribute('timestamp'),
                ];
                $intEffectRow = $this->UserAccess->updateById($arrUpdate);
                if (!$intEffectRow) return businessError();
                $this->createOperateLog($arrData, $arrUpdate);
                $boolIsThis = intval($this->request->input('userId')) === intval($this->request->getAttribute('userId'));
                return businessSuccess(['isThis' => $boolIsThis]);
        }
}